home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 242 / Issue 242 - April 2008 - DPCS0408DVD.ISO / Software Money Savers / VirtualDub / Source / VirtualDub-1.7.7-src.7z / src / system / source / VDNamespace.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2006-11-05  |  6.4 KB  |  255 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    System library component
  3. //    Copyright (C) 1998-2004 Avery Lee, All Rights Reserved.
  4. //
  5. //    Beginning with 1.6.0, the VirtualDub system library is licensed
  6. //    differently than the remainder of VirtualDub.  This particular file is
  7. //    thus licensed as follows (the "zlib" license):
  8. //
  9. //    This software is provided 'as-is', without any express or implied
  10. //    warranty.  In no event will the authors be held liable for any
  11. //    damages arising from the use of this software.
  12. //
  13. //    Permission is granted to anyone to use this software for any purpose,
  14. //    including commercial applications, and to alter it and redistribute it
  15. //    freely, subject to the following restrictions:
  16. //
  17. //    1.    The origin of this software must not be misrepresented; you must
  18. //        not claim that you wrote the original software. If you use this
  19. //        software in a product, an acknowledgment in the product
  20. //        documentation would be appreciated but is not required.
  21. //    2.    Altered source versions must be plainly marked as such, and must
  22. //        not be misrepresented as being the original software.
  23. //    3.    This notice may not be removed or altered from any source
  24. //        distribution.
  25.  
  26. #include "stdafx.h"
  27. #include <string.h>
  28. #include <ctype.h>
  29. #include <crtdbg.h>
  30.  
  31. #include <vd2/system/list.h>
  32. #include <vd2/system/VDNamespace.h>
  33.  
  34. ///////////////////////////////////////////////////////////////////////////
  35. //
  36. //    Group
  37. //
  38. ///////////////////////////////////////////////////////////////////////////
  39.  
  40. VDNamespaceGroup::VDNamespaceGroup(const char *_pszName, VDNamespaceGroup *parent)
  41. : VDNamespaceNode(namedup(_pszName),parent)
  42. {
  43.     const char *t = strchr(_pszName,'/');
  44.  
  45.     if (t) {
  46.  
  47.     } else
  48.         strcpy((char *)pszName, _pszName);
  49. }
  50.  
  51. VDNamespaceGroup::~VDNamespaceGroup() {
  52.     delete[] (char *)pszName;
  53. }
  54.  
  55. const char *VDNamespaceGroup::namedup(const char *s) {
  56.     const char *t = strchr(s,'/');
  57.     char *mem;
  58.  
  59.     if (t) {
  60.         mem = new char[(t-s)+1];
  61.  
  62.         memcpy(mem, s, (t-s));
  63.         mem[t-s] = 0;
  64.  
  65.         return mem;
  66.     } else {
  67.         mem = new char[strlen(s)+1];
  68.  
  69.         return strcpy(mem, s);
  70.     }
  71. }
  72.  
  73. ///////////////////////////////////////////////////////////////////////////
  74. //
  75. // Item
  76. //
  77. ///////////////////////////////////////////////////////////////////////////
  78.  
  79. VDNamespaceItem::VDNamespaceItem(const char *_pszName, VDNamespaceGroup *parent, const void *src)
  80. : VDNamespaceNode(_pszName,parent), object(src)
  81. {}
  82.  
  83. VDNamespaceItem::~VDNamespaceItem() {}
  84.  
  85. ///////////////////////////////////////////////////////////////////////////
  86. //
  87. //    VDNamespace
  88. //
  89. ///////////////////////////////////////////////////////////////////////////
  90.  
  91. bool VDNamespaceCompare(const char *psz1, const char *psz2) {
  92.     char c, d;
  93.  
  94.     while((!!(c=toupper(*psz1++)) & !!(d=toupper(*psz2++))) && c!='/' && d!='/' && c==d)
  95.         ;
  96.  
  97.     if (c=='/') c=0;
  98.     if (d=='/') d=0;
  99.  
  100.     return c==d;
  101. }
  102.  
  103. VDNamespace::VDNamespace() : root("", NULL) {
  104. }
  105.  
  106. VDNamespace::~VDNamespace() {
  107. }
  108.  
  109. VDNamespaceGroup *VDNamespace::_lookupGroup(const char *pszName, bool fCreate, bool fIsFilter) {
  110.     const char *pszNameLimit = pszName;
  111.     const char *slash = NULL;
  112.     VDNamespaceGroup *pGroup = &root, *pGroupNext;
  113.  
  114.     while(*pszNameLimit) {
  115.         if (*pszNameLimit++ == '/')
  116.             slash = pszNameLimit - 1;
  117.     }
  118.  
  119.     if (fIsFilter)
  120.         pszNameLimit = slash;
  121.  
  122.     while(pszName < pszNameLimit) {
  123.         VDNamespaceGroup *pGroupParent = pGroup;
  124.  
  125.         pGroup = pGroup->listGroups.AtHead();
  126.  
  127.         while(pGroupNext = pGroup->NextFromHead()) {
  128.             if (VDNamespaceCompare(pszName, pGroup->pszName))
  129.                 break;
  130.  
  131.             pGroup = pGroupNext;
  132.         }
  133.  
  134.         if (!pGroupNext && fCreate) {
  135.             pGroupNext = pGroup = new VDNamespaceGroup(pszName, pGroupParent);
  136.  
  137.             pGroupParent->listGroups.AddTail(pGroup);
  138.         }
  139.  
  140.         // group not found?
  141.  
  142.         if (!pGroupNext) {
  143.             return NULL;
  144.         }
  145.  
  146.         // advance to next slash
  147.  
  148.         while(*pszName && *pszName++!='/')
  149.             ;
  150.     }
  151.  
  152.     return pGroup;
  153. }
  154.  
  155. void VDNamespace::clear() {
  156.     root.listGroups.dispose();
  157.     root.listItems.dispose();
  158. }
  159.  
  160. void VDNamespace::add(const char *pszGroup, const char *pszName, const void *pDef) {
  161.     VDNamespaceGroup *pGroup = _lookupGroup(pszGroup, true, false);
  162.     
  163.     pGroup->listItems.AddTail(new VDNamespaceItem(pszName, pGroup, pDef));
  164. }
  165.  
  166. const void *VDNamespace::lookup(const char *pszName) {
  167.     VDNamespaceGroup *pGroup = _lookupGroup(pszName, false, true);
  168.  
  169.     if (!pGroup)
  170.         return NULL;
  171.  
  172.     const char *pszNameBase = pszName;
  173.  
  174.     while(*pszName++)
  175.         if (pszName[-1]=='/')
  176.             pszNameBase = pszName;
  177.  
  178.     for(ListAlloc<VDNamespaceItem >::fwit it = pGroup->listItems.begin(); it; ++it)
  179.         if (!_stricmp(it->pszName, pszNameBase))
  180.             return it->object;
  181.  
  182.     return NULL;
  183. }
  184.  
  185. bool VDNamespace::enumerateGroups(const VDNamespaceGroup *pGroupRoot, tGroupEnumerator pEnum, void *pvData) {
  186.     VDNamespaceGroup *pGroup, *pGroupNext;
  187.  
  188.     pGroup = (pGroupRoot ? pGroupRoot : &root)->listGroups.AtHead();
  189.     while(pGroupNext = pGroup->NextFromHead()) {
  190.         if (!pEnum(this, pGroup->pszName, pGroup, pvData))
  191.             return false;
  192.  
  193.         pGroup = pGroupNext;
  194.     }
  195.  
  196.     return true;
  197. }
  198.  
  199. bool VDNamespace::enumerateItems(const VDNamespaceGroup *pGroupRoot, tItemEnumerator pEnum, void *pvData) {
  200.     VDNamespaceItem *pEntry, *pEntryNext;
  201.  
  202.     pEntry = pGroupRoot->listItems.AtHead();
  203.     while(pEntryNext = pEntry->NextFromHead()) {
  204.         if (!pEnum(this, pEntry->pszName, pEntry->object, pvData))
  205.             return false;
  206.  
  207.         pEntry = pEntryNext;
  208.     }
  209.  
  210.     return true;
  211. }
  212.  
  213. VDNamespaceItem *VDNamespace::_findItemByObject(const VDNamespaceGroup *pGroup, const void *pObj) {
  214.     for(ListAlloc<VDNamespaceItem>::fwit it=pGroup->listItems.begin(); it; ++it) {
  215.         if (it->object == pObj) {
  216.             return it;
  217.         }
  218.     }
  219.  
  220.     for(ListAlloc<VDNamespaceGroup>::fwit it2=pGroup->listGroups.begin(); it2; ++it2) {
  221.         VDNamespaceItem *v;
  222.  
  223.         if (v = _findItemByObject(it2, pObj))
  224.             return v;
  225.     }
  226.  
  227.     return NULL;
  228. }
  229.  
  230. bool VDNamespace::_getPathByItem(const VDNamespaceNode *pEntry, char *buf, int maxlen) {
  231.     if (!pEntry)
  232.         return false;
  233.  
  234.     if (maxlen < (int)strlen(pEntry->pszName)+2)
  235.         return false;
  236.  
  237.     if (pEntry->pParent && pEntry->pParent->pParent) {
  238.         if (!_getPathByItem(pEntry->pParent, buf, maxlen))
  239.             return false;
  240.  
  241.         while(*buf)
  242.             ++buf, --maxlen;
  243.  
  244.         *buf++ = '/';
  245.     }
  246.  
  247.     strcpy(buf, pEntry->pszName);
  248.  
  249.     return true;
  250. }
  251.  
  252. bool VDNamespace::getPathByItem(const void *pObj, char *buf, int maxlen) {
  253.     return _getPathByItem(_findItemByObject(&root, pObj), buf, maxlen);
  254. }
  255.